import asyncio
import datetime
from collections import defaultdict
from pathlib import Path
import platform
from typing import *
from decimal import Decimal, getcontext

import warnings
import pandas as pd

warnings.filterwarnings("ignore")
pd.set_option('display.max_columns', 20)
pd.set_option('display.max_rows', 20)

# 静默异步事件循环关闭错误
if platform.system() == 'Windows':
    from asyncio.proactor_events import _ProactorBasePipeTransport


    def silent(func: Callable):
        def wrapper(*args, **kwargs):
            try:
                return func(*args, **kwargs)
            except RuntimeError as e:
                if str(e) != 'Event loop is closed':
                    raise e

        return wrapper


    _ProactorBasePipeTransport.__del__ = silent(_ProactorBasePipeTransport.__del__)

getcontext().prec = 20

ROOT_DIR: str = Path(__file__).parent.absolute().__str__()

# 数据库配置，目前支持mysql和pg，数据库相关逻辑在util/data
# 数据库IO耗时较长
DATABASE: Optional[Dict[str, Any]] = {
    'mysql': {
        'host': '127.0.0.1',
        'port': 3306,
        'db': 'backtest',
        'username': 'root',
        'password': '064735Freedom?',
    },
    'clickhouse': None,
    'postgresql': {
        'host': '127.0.0.1',
        'port': 5432,
        'db': 'binance',
        'username': 'postgres',
        'password': '064735',
    },
}

# 存储数据库 mysql postgresql
DATABASE_TYPE: str = 'postgresql'

# 代理 数据加载需要访问币安，不在下载数据则无需配置
PROXY_CONF: Dict[str, Any] = {
    'http': 'http://localhost:7890',
    'https': 'http://localhost:7890',
    # 'http': 'http://192.168.1.5:7874',
    # 'https': 'http://192.168.1.5:7874',
}

# 数据加载方式 append-追加 init-重置数据库 null不检查 其他则重新下载当前配置数据
DATA_PREPARE_CONF: str = 'null'

# 运行时数据缓冲，缓冲数据越大越消耗内存，但是访问数据库频率下降，提升运行速度
DATA_BUFFER_SIZE: int = 500

# 默认交易限制规则，为false时从币安获取
DEFAULT_TRADE_RULE: bool = True

# 不可配置
BASE_ASSET = 'USDT'
# 下载数据时完全排除的币种类型
STABLE_SYMBOL = ['BKRW', 'USDC', 'USDP', 'TUSD', 'BUSD', 'FDUSD', 'DAI', 'EUR', 'GBP']

# 最低保证金率
min_margin_ratio = 1 / 100

# 手续费
PREMIUM = {
    'spot': {
        'maker': Decimal('0.001'),
        'taker': Decimal('0.002'),
    },
    'swap': {
        'maker': Decimal('0.0002'),
        'taker': Decimal('0.0005'),
    },
    # 强平手续费
    'force': Decimal('0.0105'),
}

# 仿盘实盘拆单设置
SPLIT_ORDER: bool = False
SPLIT_AMOUNT: Decimal = Decimal(200)

# 仿盘起始资金
ORIGIN_BALANCE: Decimal = Decimal(10000)

# ===== 输出信息 =====
# 输出结果归一化
NORMALIZATION = True
# 输出交易日志，日志保存位置为./locals/output/trade-{策略名}.csv
TRADE_LOG: bool = True
# 输出策略中的打印信息 保存位置为./locals/output/stdout-{策略名}.log，
# 开启后将策略中的print信息重定向到文件中，关闭后print信息会丢弃
STRATEGY_LOG: bool = True
# 回测特殊数据收集和整理，整理逻辑在util/dataArrange/dataHandler
BACKTEST_DATA_COLLECTION: bool = True
